﻿using K9Nano.Application.Dtos;
using K9Nano.Dependency;
using K9Nano.Exceptions;
using K9Nano.Reporting;
using K9Nano.Resources;

namespace K9Nano.Application.Reporting;

internal class ReportAppService(IReportManager manager, IReportEngine engine, IResourceManager resourceManager)
    : IReportAppService, IScopedDependency
{
    public virtual async Task<ReportResult> QueryAsync(ReportQueryDto dto, CancellationToken cancellation)
    {
        var report = await manager.GetAsync(dto.Id, cancellation)
            ?? throw FriendlyException.BadRequest($"ID为{dto.Id}的报表不存在");
        if (!report.IsEnabled)
        {
            throw FriendlyException.BadRequest($"ID为{dto.Id}的报表未启用");
        }

        var parameters = report.PrepareReportParameters(dto.PageIndex, dto.PageSize, dto.Parameters);
        var result = await engine.ExectueAsync(report, parameters, cancellation);
        return result;
    }

    /// <inheritdoc/>
    public virtual async Task<string> ExportAsync(ReportExportDto dto, CancellationToken cancellation)
    {
        var report = await manager.GetAsync(dto.Id, cancellation)
            ?? throw FriendlyException.BadRequest($"ID为{dto.Id}的报表不存在");
        if (!report.IsEnabled)
        {
            throw FriendlyException.BadRequest($"ID为{dto.Id}的报表未启用");
        }

        var parameters = report.PrepareReportParameters(0, 0, dto.Parameters);
        var result = await engine.ExportAsync(report, parameters, cancellation);
        var res = new FileResource(result, report.DisplayName + "导出数据.xlsx");
        resourceManager.Protect(res, TimeSpan.FromMinutes(5));
        return res.Id;
    }

    public Task DeleteAsync(int id, CancellationToken cancellation)
        => manager.DeleteAsync(id, cancellation);

    public Task<Report?> GetAsync(int id, CancellationToken cancellation)
        => manager.GetAsync(id, cancellation);

    public Task<ReportForm?> GetReportFormAsync(int id, CancellationToken cancellation)
         => manager.GetReportFormAsync(id, cancellation);

    public Task<IEnumerable<ReportSummary>> GetReportSummariesAsync(CancellationToken cancellation)
         => manager.GetReportSummariesAsync(cancellation);

    public Task SaveAsync(Report report, CancellationToken cancellation)
         => manager.SaveAsync(report, cancellation);

    public Task<bool> SetStatusAsync(int id, bool isEnabled, CancellationToken cancellation)
         => manager.SetStatusAsync(id, isEnabled, cancellation);
}
